﻿using Smile.Mvvm.Command;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;

namespace Smile.Mvvm.ViewModel
{
    public abstract class ViewModelBase : INotifyPropertyChanged
    {
        // @Events
        public event PropertyChangedEventHandler PropertyChanged;


        // @Properties
        public bool IsBeingProcessed
        {
            get
            {
                return _isBeingProcessed;
            }
            set
            {
                if (value != _isBeingProcessed)
                {
                    _isBeingProcessed = value;
                    RaisePropertyChanged();
                    RefreshCommands();
                }
            }
        }


        // @Public
        public ViewModelBase()
        {
            InitializeServices();
            SubscribeMessenger();
            InitializeCommands();
        }

        public void SetCommand(ISmileCommand command, [CallerMemberName] string commandName = "")
        {
            _commands[commandName] = command;
        }

        public ISmileCommand GetCommand([CallerMemberName] string commandName = "")
        {
            ISmileCommand command = null;
            _commands.TryGetValue(commandName, out command);
            return command;
        }

        public void RefreshCommands()
        {
            foreach (ISmileCommand element in _commands.Values)
            {
                element.RefreshCanExecuteChanged();
            }
        }


        // @protected
        protected bool _isBeingProcessed = false;
        protected Dictionary<string, ISmileCommand> _commands = new Dictionary<string, ISmileCommand>();


        protected abstract void InitializeServices();
        protected abstract void InitializeCommands();
        protected abstract void SubscribeMessenger();


        protected void RaisePropertyChanged([CallerMemberName] string propertyName = "")
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}
